package com.lantosec.hmrp.modules.workflow.listener;

import com.alibaba.fastjson.JSONObject;
import com.lantosec.hmrp.core.exception.AppException;
import com.lantosec.hmrp.core.util.DateUtils;
import com.lantosec.hmrp.core.util.FlowableUtils;
import com.lantosec.hmrp.modules.sysdata.entity.SysProcessForm;
import com.lantosec.hmrp.modules.sysdata.service.ISysDataProcessService;
import com.lantosec.hmrp.modules.sysdata.service.ISysDataProcessTaskService;
import com.lantosec.hmrp.modules.sysdata.service.ISysProcessFormService;
import com.lantosec.hmrp.modules.workflow.enumeration.ProcessVariableEnum;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 流程启动监听事件
 *
 * @author lichaowei
 * @date 2020/5/27
 */
@Component
@Log4j2
public class ProcessStartListener implements ExecutionListener {
    private static final long serialVersionUID = 1L;

    @Autowired
    ISysDataProcessService sysDataProcessService;
    @Autowired
    private ISysProcessFormService sysProcessFormService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ISysDataProcessTaskService sysDataProcessTaskService;

    @Override
    public void notify(DelegateExecution delegateExecution) {
        String processInstanceId = delegateExecution.getProcessInstanceId();
        String processDefinitionId = delegateExecution.getProcessDefinitionId();
        log.info("流程启动监听事件----->processInstanceId:" + delegateExecution.getProcessInstanceId());

        SysProcessForm sysProcessForm = sysProcessFormService.selectByDefinitionId(processDefinitionId);
        if (Objects.isNull(sysProcessForm)) {
            throw new AppException("查询流程定义与表单的关系失败");
        }
        // 设置流程名称
        JSONObject dataJson = (JSONObject) delegateExecution.getVariable(ProcessVariableEnum.BUSINESS_DATA.getCode());
        String processInstanceName = getProcessName(sysProcessForm, dataJson);
        runtimeService.setProcessInstanceName(processInstanceId, processInstanceName);

        String businessKey = delegateExecution.getProcessInstanceBusinessKey();
        if (StringUtils.isEmpty(businessKey)) {
            // 设置流程业务Key，子流程设置用，在CallActivityStartListener插入数据
            businessKey = (String) delegateExecution.getVariable(ProcessVariableEnum.BUSINESS_KEY.getCode());
            runtimeService.updateBusinessKey(processInstanceId, businessKey);
        }
        //获取流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        String firstTaskId = FlowableUtils.getFirstUserTaskId(bpmnModel);

        String startUserId = (String) delegateExecution.getVariable(ProcessVariableEnum.USER_ID.getCode());
        //保存流程实例与数据的关系
        sysDataProcessService.insertProcess(sysProcessForm.getFormTableId(), processDefinitionId, sysProcessForm.getDeploymentId()
                , processInstanceId, processInstanceName, businessKey, delegateExecution.getCurrentActivityId(), firstTaskId
                , "", startUserId, sysProcessForm.getProcessType());

        String userId = (String) delegateExecution.getVariable(ProcessVariableEnum.USER_ID.getCode());
        sysDataProcessTaskService.insertTask(processInstanceId, "", userId, "", Boolean.TRUE);
    }


    private String getProcessName(SysProcessForm processForm, JSONObject dataJson){
        if(Objects.isNull(processForm)){
            return "";
        }
        if(Objects.isNull(dataJson)){
            dataJson = new JSONObject();
        }
        //  获取流程名称规则 ${userName}的${processName}-${today}
        String rule = processForm.getProInsNameRule();
        dataJson.put("processName", processForm.getProcessName());
        dataJson.put("today", DateUtils.getNowDate());
        return com.lantosec.hmrp.core.util.StringUtils.processTemplate(rule, dataJson);
    }
}
